package com.geniusk.system.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.GifCaptcha;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.geniusk.common.config.IoTConfig;
import com.geniusk.common.constant.CaptchaConstants;
import com.geniusk.common.constant.RedisConstants;
import com.geniusk.common.core.JSONResult;
import com.geniusk.common.utils.RedisUtil;
import com.geniusk.security.enums.LoginSourceType;
import com.geniusk.system.model.bo.passport.LoginBO;
import com.geniusk.system.model.pojo.Menu;
import com.geniusk.system.model.pojo.User;
import com.geniusk.security.utils.SecurityUtil;
import com.geniusk.security.utils.TokenUtil;
import com.geniusk.system.utils.LoginUtil;
import com.geniusk.system.service.MenuService;
import com.geniusk.system.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 注册登录接口
 */
@RestController
@RequestMapping("/system/passport")
public class PassportController {

    @Autowired
    private LoginUtil loginUtil;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private UserService userService;

    @Autowired
    private MenuService menuService;

    @Autowired
    private TokenUtil tokenUtil;

    @Autowired
    private IoTConfig ioTConfig;

    /**
     * 获取图片验证码
     */
    @GetMapping("/getCheckImage")
    public JSONResult getCheckImage() {
        Map<String, Object> result = new HashMap<>();
        //生成uuid
        String checkId = IdUtil.fastUUID();
        String captchaType = ioTConfig.getCaptchaType();
        //生成验证码
        if(captchaType.equals(CaptchaConstants.MATH_CHAR)){
            LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 45, 4, 10);
            result.put("checkId", checkId);
            //获取验证码的base64
            result.put("checkImg", lineCaptcha.getImageBase64Data());
            result.put("useCheckImage", CaptchaConstants.TRUE.equals(ioTConfig.getCaptchaEnabled()));
            //获取验证码内容
            String checkData = lineCaptcha.getCode();
            redisUtil.setCacheObject(getCheckId(checkId), checkData, 60, TimeUnit.SECONDS);
        }else {
            GifCaptcha gifCaptcha = CaptchaUtil.createGifCaptcha(200, 45,4);
            result.put("checkId", checkId);
            //获取验证码的base64
            result.put("checkImg", gifCaptcha.getImageBase64Data());
            result.put("useCheckImage", CaptchaConstants.TRUE.equals(ioTConfig.getCaptchaEnabled()));
            //获取验证码内容
            String checkData = gifCaptcha.getCode();
            redisUtil.setCacheObject(getCheckId(checkId), checkData, 60, TimeUnit.SECONDS);
        }

        return JSONResult.ok(result);
    }

    /**
     * 用户登陆
     */
    @PostMapping("/login")
    public JSONResult login(@Valid @RequestBody LoginBO loginBO) {
        if(CaptchaConstants.TRUE.equals(ioTConfig.getCaptchaEnabled())){
            //校验验证码
            String checkId = getCheckId(loginBO.getCheckId());
            Boolean hasKey = redisUtil.hasKey(checkId);
            //判断key是否存在，不存在返回失效
            if (hasKey == null || !hasKey) {
                return JSONResult.errorMsg("验证码失效，请刷新验证码");
            }
            //验证内容是否相同
            String checkData = redisUtil.getCacheObject(checkId);
            String checkCode = loginBO.getCheckCode();
            if (!StrUtil.equalsIgnoreCase(checkData, checkCode)){
                return JSONResult.errorMsg("验证码错误");
            }
            redisUtil.deleteObject(checkId);
        }
        String token = loginUtil.getLoginToken(loginBO.getUsername(),loginBO.getPassword(), LoginSourceType.PC_LOGIN);
        return JSONResult.loginSucceed(token);
    }

    /**
     * 获取用户信息
     */
    @GetMapping("getUserInfo")
    public JSONResult getUserInfo() {
        User user = userService.selectUserById(SecurityUtil.getUserId());
        // 权限集合
        Set<String> funcPermissions = menuService.selectPermissionByUserId(user.getUserId());
        Map<String,Object> result = new HashMap<>();
        result.put("user",user);
        result.put("permissions", funcPermissions);
        return JSONResult.ok(result);
    }

    /**
     * 获取路由信息
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public JSONResult getRouters() {
        Long userId = SecurityUtil.getUserId();
        Map<String,Object> result = new HashMap<>();
        if(SecurityUtil.getLoginUser().getIsRoot()){
            List<Menu> menus = menuService.selectAllMenu(new Menu());
            result.put("menus",menus);
        }else{
            HashMap<String,Object> hashMap = new HashMap<>();
            hashMap.put("userId",userId);
            List<Menu> menus = menuService.selectMenuByUserId(hashMap);
            result.put("menus",menus);
        }
        return JSONResult.ok(result);
    }

    /**
     * 退出登录
     * @return 退出结果
     */
    @GetMapping("/logout")
    public JSONResult logout() {
        try {
            Long identityId = SecurityUtil.getLoginUser().getIdentityId();
            tokenUtil.delLoginUserByIdentityId(identityId);
        }catch (Exception e){
            return JSONResult.ok("退出成功");
        }
        return JSONResult.ok("退出成功");
    }

    /**
     * 添加redis key前缀
     * @param uuid 验证码id
     * @return redis key
     */
    private String getCheckId(String uuid) {
        return RedisConstants.LOGIN_CHECK_ID + uuid;
    }

}
